package com.example.demo2.service.impl;

import com.example.demo2.entity.ComparisonName;
import com.example.demo2.entity.ComparisonResults;
import com.example.demo2.entity.Result;
import com.example.demo2.entity.UploadedData;
import com.example.demo2.mapper.ComparisonNameMapper;
import com.example.demo2.mapper.ComparisonResultsMapper;
import com.example.demo2.mapper.ResultMapper;
import com.example.demo2.mapper.UploadedDataMapper;
import com.example.demo2.service.ComparisonBatchProcessService;
import com.example.demo2.service.ComparisonService;
import com.example.demo2.service.ResultService;
import com.example.demo2.service.UploadedDataService;
import com.example.demo2.util.JobProgress;
import com.example.demo2.util.ResultIndex;
import org.apache.poi.ss.usermodel.Cell;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author
 * @version 1.0
 * @description TODO
 * @date 2024/7/1 9:48
 */
@Service
public class ComparisonServiceImpl implements ComparisonService {

    private static final Logger logger = LoggerFactory.getLogger(ComparisonServiceImpl.class);
    private Map<String, JobProgress> progressMap = new ConcurrentHashMap<>();

    @Autowired
    private ComparisonBatchProcessService batchProcessService;

    @Autowired
    private UploadedDataMapper uploadedDataMapper;

    @Autowired
    private ResultMapper resultMapper;

    @Autowired
    private ResultService resultService;

    @Autowired
    private ComparisonResultsMapper comparisonResultsMapper;

    @Autowired
    private UploadedDataService uploadedDataService;

    @Autowired
    private ComparisonNameMapper comparisonNameMapper;

    private double getCellValueAsDouble(Cell cell) {
        switch (cell.getCellType()) {
            case NUMERIC:
                return cell.getNumericCellValue();
            case STRING:
                String cellValue = cell.getStringCellValue().trim();
                if (cellValue.isEmpty()) {
                    throw new IllegalArgumentException("Empty cell value encountered.");
                }
                try {
                    return Double.parseDouble(cellValue);
                } catch (NumberFormatException e) {
                    throw new IllegalArgumentException("Invalid numeric value in cell: " + cellValue);
                }
            case BOOLEAN:
                return cell.getBooleanCellValue() ? 1.0 : 0.0;
            case FORMULA:
                return cell.getNumericCellValue();
            default:
                throw new IllegalArgumentException("Unsupported cell type: " + cell.getCellType());
        }
    }

    @Override
    public Page<ComparisonResults> getComparisonResults(String name, int page, int size) throws Exception {
        logger.info("获取比较结果，name: {}, page: {}, size: {}", name, page, size);

        try {
            int offset = page * size;
            List<ComparisonResults> results = comparisonResultsMapper.findByName(name, offset, size);
            long total = comparisonResultsMapper.countByName(name);

            logger.info("获取到 {} 条比较结果，总数: {}", results.size(), total);

            return new PageImpl<>(results, PageRequest.of(page, size), total);
        } catch (Exception e) {
            logger.error("获取比较结果时发生错误", e);
            throw e;
        }
    }
    @Override
    @Async
    public String startComparison(String resultName, String uploadName, double tolerance,String comparisonName) {
        String jobId = UUID.randomUUID().toString();

        // 保存比较名称
        ComparisonName comparisonNameEntity = new ComparisonName();
        comparisonNameEntity.setResultName(resultName);
        comparisonNameEntity.setUploadName(uploadName);
        comparisonNameEntity.setComparisonName(comparisonName);
        comparisonNameMapper.insertComparisonName(comparisonNameEntity);

        // 开始比较过程
        progressMap.put(jobId, new JobProgress());

        List<Result> results = resultService.getResultsByName(resultName);
        ResultIndex resultIndex = new ResultIndex();
        results.forEach(resultIndex::addResult);

        int totalUploadedData = uploadedDataService.countByUploadName(uploadName);
        int batchSize = 1000; // 可以根据实际情况调整
        int totalBatches = (int) Math.ceil((double) totalUploadedData / batchSize);

        for (int i = 0; i < totalBatches; i++) {
            batchProcessService.processUploadedDataBatch(jobId, i, batchSize, uploadName, resultIndex, tolerance, totalUploadedData, progressMap,comparisonName);
        }
        batchProcessService.finalizeComparison(jobId, comparisonName);
        return jobId;
    }


    @Override
    public int getProgress(String jobId) {
        JobProgress progress = progressMap.get(jobId);
        return progress != null ? progress.getProgress() : 0;
    }


}